from fastapi import APIRouter,Depends
from sqlalchemy import desc,asc
from model.downmine_data import DownmineData
from model.equipment_drill import EquipmentDrill
from model.equipment_sensor import EquipmentSensorTable
from sqlalchemy.orm import Session
from db.mysql import get_db
from vendor.extend.courier import *
from vendor.library.many_points_stress.sort_point import process_wavelength_data
from vendor.library.many_points_stress.many_points_stress import calculate_stress_points
import numpy as np
import datetime
import time
from dateutil.relativedelta import relativedelta
from vendor.extend.conversion import is_positive_integer,is_index_valid
from sqlalchemy import desc,asc,and_

Detection = APIRouter()



@Detection.get('/forms')
async def forms(date_time:int=0,category:int=0,drill_id:int=0,equipment_id:int=0, db: Session = Depends(get_db)):
    if (not isinstance(date_time, int,) or date_time<1) and category in [1,2,3]:
        return Error(msg='时间戳格式错误')
    end_time=date_time
    if category==1:
        start_time=date_time-86400
    elif category==2:
        start_time=date_time-604800
    elif category==3:
        # 将Unix时间戳转换为datetime对象
        dt_object = datetime.datetime.fromtimestamp(date_time)
        new_dt = dt_object - relativedelta(months=1)
        # 将结果转换回Unix时间戳
        start_time = int(new_dt.timestamp())
    else:
        end_time=int(time.time())
        start_time=end_time-86400


    list_data=db.query(DownmineData).filter(DownmineData.create_time>start_time,DownmineData.create_time<end_time).order_by(desc("id")).all()



    # 通道数据
    channel_arr=[]

    # 格式化钻孔数据
    drill_obj={}
    conditions=[]
    if is_positive_integer(equipment_id):
        conditions.append(EquipmentDrill.equipment_id==equipment_id)
    if is_positive_integer(drill_id):
        conditions.append(EquipmentDrill.id==drill_id)
    # 查找数据中的所有管道和传感器
    drill_list=db.query(EquipmentDrill).filter(and_(*conditions)).all()
    if not drill_list:
        return Error(msg='未找到相关传感器')

    # 光栅波长数据
    wavelength_obj={}
    # 每个光栅深度
    depth_obj = {}
    # 光栅1比例系数K λ
    factor_obj = {}
    for info in drill_list:
        sensor_info=db.query(EquipmentSensorTable).filter_by(drill_id=info.id).order_by(desc("id")).first()
        if sensor_info:
            wavelength_obj[info.channel]=[row['wavelength'] for row in sensor_info.raster_data]
            depth_obj[info.channel] = [row['depth'] for row in sensor_info.raster_data]
            factor_obj[info.channel] = [row['factor'] for row in sensor_info.raster_data]
            drill_obj[info.channel]={
                "id":info.id,
                "equipment_id":info.equipment_id,
                'identifier':info.identifier,
                'channel':info.channel,
                'x':info.x,
                'y':info.y,
                'z':info.z,
                'sensor':{
                    "id":sensor_info.id,
                    "numbering":sensor_info.numbering,
                    "raster_total":sensor_info.raster_total,
                    "raster_data":sensor_info.raster_data
                }
            }

    ordered_data={} #排序数据
    raw_wavelength_data={}
    # 传入的设计波长 后台配置
    #design_wavelengths = [1529.948, 1533.435,  1540.348, 1536.698, 1547.937, 1543.769, 1551.826, 1555.261, 1558.858, 1562.280]
    design_wavelengths=[0 for _ in range(10)]
    # 传入的点数
    point_num = 10
    for info in list_data:
        channel_num=info.line

        if channel_num in wavelength_obj:
            channel_arr.append(channel_num)
            if ordered_data.get(channel_num) is None:
                ordered_data[channel_num]=[]
            raw_wavelength_data[channel_num]=info.data[:point_num]

            # 获得所有光栅1设计波长λ
            wavelength_data = wavelength_obj[channel_num]
            design_wavelengths=wavelength_data[0:point_num]

            # 光栅数据排序
            analysis_report, processed_data, need_analysis, abnormal_positions= process_wavelength_data(design_wavelengths, raw_wavelength_data, point_num, channel_num)
            ordered_data[channel_num].append(processed_data)


    # 波长初始化数据集合
    initialize_wavelengths_obj={}
    create_info=db.query(DownmineData.create_time).order_by(asc("id")).first()
    initial_time=create_info.create_time+300
    unique_list = list(set(channel_arr))
    #print('初始值排序')
    for corridor in unique_list:
        channel_num=corridor
        # 获得所有光栅1设计波长λ
        wavelength_data = wavelength_obj[channel_num]
        design_wavelengths=wavelength_data[0:point_num]
        data_info=db.query(DownmineData.data).filter(DownmineData.line==corridor,DownmineData.create_time>initial_time).order_by(asc("id")).first()
        raw_wavelength_data[channel_num]=data_info.data[:point_num]
        # print(wavelength_data)
        # print("design_wavelengths",design_wavelengths)
        # print("raw_wavelength_data",raw_wavelength_data)
        # print("point_num",point_num)
        # print("channel_num",channel_num)
        analysis_report, processed_data, need_analysis, abnormal_positions= process_wavelength_data(design_wavelengths, raw_wavelength_data, point_num, channel_num)
        # 排序完成的初始值
        initialize_wavelengths_obj[channel_num]=processed_data
        #print(processed_data)


    # 截取的初始波长 历史数据开始五分钟后第一条数据
    #initial_wavelengths = [1529.948, 1533.435, 1540.348, 1536.698, 1547.937, 1543.769, 1551.826, 1555.261, 1558.858, 1562.280]
    # 传入的光栅点比例系数（由深入浅）
    coefficients = [0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4]
    stress_list={} # 计算应力值

    # 初始值
    for key, value in ordered_data.items():
        if key in drill_obj:
            # 光栅1比例系数K λ
            factor_data = factor_obj[key]
            coefficients[0:len(factor_data)]=factor_data
            initial_wavelengths=initialize_wavelengths_obj[key]

            if key not in stress_list:
                stress_list[key]=[]
            for item in value:
                # 计算调整后的值
                adjusted_values = calculate_stress_points(item, initial_wavelengths, coefficients)
                stress_list[key].append(adjusted_values)

    data_list=[]
    for k, arr in stress_list.items():
        drill_info=drill_obj.get(k)
        if not drill_info:
            continue

        # 列表数据转numpy列表
        arr_with_zero = np.array(arr)
        # 将None转换为nan
        arr_with_zero[arr_with_zero == None] = np.nan
        # 取每列最大值
        max_values = np.max(arr_with_zero, axis=0)

        # 转成队列
        list_max = max_values.tolist()
        # 获得第一条最新数据
        initial=arr_with_zero[0].tolist()

        # 数列中的最后一行None转换成0
        adjusted_array = [0 if x is None else x for x in arr[-1]]
        # 使用列表推导式逐个相减
        growth_rate = [a - b for a, b in zip(initial, adjusted_array)]

        drill_list={}
        sensor_info=drill_info['sensor']
        if drill_info:
            drill_list={
                "equipment_id":drill_info['equipment_id'],
                'drill_id':drill_info['id'],
                'drill_identifier':drill_info['identifier'],
                'drill_channel':drill_info['channel'],
                'drill_x':drill_info['x'],
                'drill_y':drill_info['y'],
                'drill_z':drill_info['z'],
                'sensor':{
                    "id":sensor_info['id'],
                    "numbering":sensor_info['numbering'],
                    "raster_total":sensor_info['raster_total']
                }
            }
        initial_arr=[]
        stress_max_arr=[]
        growth_rate_arr=[]

        for index, item in enumerate(initial):
            depth=None
            if index in range(len(depth_obj[k])):
                depth=depth_obj[k][index]

            initial_arr.append({
                'depth':depth,
                'stress':item
            })
            max_stress=None
            if index in range(len(list_max)):
                max_stress=list_max[index]
            stress_max_arr.append({
                'depth':depth,
                'stress':max_stress
            })
            rate_stress=None
            if index in range(len(growth_rate)):
                rate_stress=growth_rate[index]
            growth_rate_arr.append({
                'depth':depth,
                'stress':rate_stress
            })

        data_list.append(
            {
                'initial':initial_arr, #最新实时
                'stress_max':stress_max_arr, #每列最大值
                'growth_rate':growth_rate_arr, #增幅
                'growth_up':growth_rate_arr, #增速
                'drill':drill_list
            }
        )

    return Success(data=data_list)
